package com.beidu.lottery.call.utils.concurrent;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 分布式锁工具类
 * <p>
 * 使用RedissonClient实现分布式锁.
 *
 * @author huangzhihao
 */
@Component
@SuppressWarnings("unused")
public class RedissonClientUtil {

    /**
     * RedissonClient，用于实现分布式锁
     */
    @Resource
    private RedissonClient redissonClient;

    /**
     * 该方法接受一个Consumer对象作为参数，无返回值
     *
     * @param key      键
     * @param consumer 函数
     * @param <T>      数据泛型
     * @author 北渡
     */
    public <T> void executeWithLock(T key, Consumer<T> consumer) {
        RLock lock = redissonClient.getLock(key + ":lock");
        try {
            lock.lock();
            consumer.accept(key);
        } finally {
            lock.unlock();
        }
    }

    /**
     * 该方法接受一个Supplier对象作为参数，用于执行有返回值的函数
     *
     * @param key      键
     * @param supplier 函数
     * @param <T>      数据泛型
     * @return Supplier的返回值
     * @author 北渡
     */
    public <T> T executeWithLock(String key, Supplier<T> supplier) {
        RLock lock = redissonClient.getLock(key + ":lock");
        try {
            lock.lock();
            return supplier.get();
        } finally {
            lock.unlock();
        }
    }

}
